package com.flower.sequence.parse;

import com.flower.sequence.service.SegmentGenerator;
import com.flower.sequence.service.string.CompositeStringSequenceGenerator;
import com.flower.sequence.utils.SpringUtil;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.List;

import static org.apache.logging.log4j.util.Strings.trimToNull;

/**
 * @author shanks on 2019-10-11
 */
public class CompositeBeanDefinitionParse extends AbstractSingleBeanDefinitionParser {

    @Override
    protected Class<?> getBeanClass(Element element) {
        return CompositeStringSequenceGenerator.class;
    }


    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        super.doParse(element, parserContext, builder);
        NodeList childNodes = element.getChildNodes();
        List<Object> subElements = new ArrayList<>(childNodes.getLength());
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node node = childNodes.item(i);
            if (node instanceof Element) {
                Element subElement = (Element) node;
                BeanDefinitionHolder segment = parseConfigurationPointBean(subElement, parserContext,  builder);
                subElements.add(segment);
            }
        }
        builder.addPropertyValue("segmentGenerators", subElements);
    }


    private BeanDefinitionHolder parseConfigurationPointBean(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        BeanDefinitionParserDelegate delegate = parserContext.getDelegate();
        BeanDefinition containingBean = builder.getRawBeanDefinition();

        AbstractBeanDefinition bean = (AbstractBeanDefinition) delegate.parseCustomElement(element, containingBean);
        // 解析custom element。
        String beanName = trimToNull(element.getAttribute("id"));
        if (beanName == null) {
            beanName = BeanDefinitionReaderUtils.generateBeanName(bean,parserContext.getRegistry(),false);
        }
        return new BeanDefinitionHolder(bean,beanName);
    }
}
